﻿// * @modified by Natalia Ukhorskaya
package gui.hug;

  import flash.display.DisplayObject;
  import flash.display.DisplayObjectContainer;
  import gui.hug.HUGSprite;
  import flash.events.Event;
  import flash.events.MouseEvent;

  import gui.hug.Utils;
   
class HUGScrollBar extends HUGSprite
  {
    public var lineScrollSize: UInt;

    private var arrow1 : HUGScrollButton;
    private var arrow2 : HUGScrollButton;
    private var slider : HUGSprite;

    private var maxPos : Int; // max scroll position
    private var pageSz : Int; // page size
    private var h : UInt;
    
    private var isOver : Bool;
    
    private var sliderMaxY : UInt;
    private var sliderLen : UInt;
    
    private var dragging : Bool;
    private var dragY : Float;
    
    private var trasp_bg : HUGSprite;
    
    private var curPos : Float;
	
	//public var scrollPosition(get, set): Int;
    
    private static inline var SLIDER_POS_Y:UInt = 16;
    private static inline var SLIDER_MIN_LEN:UInt = 10;
    private static inline var LINE_POS_X:UInt = 12;
    private static inline var LINE_POS_Y:UInt = 8;
    public static inline var W: Float = 16;
    public static inline var MIN_H:Float = 33 + SLIDER_MIN_LEN;

    public function new(x:Int, y:Int, h:Int )
    {
	  super();
	  lineScrollSize = 3;
	  arrow1 = null;
	  arrow2 = null;
	  slider = null;
	  maxPos = 0; // max scroll position
	  pageSz = 1; // page size
    
      isOver = false;
    
      sliderMaxY = 0;
      sliderLen = 40;
    
      dragging = false;
      dragY = 0;
    
      trasp_bg = null;
    
      curPos = 0;
	   
      this.x = x;
      this.y = y;
      this.h = h;
     
      trasp_bg = new HUGSprite();
      Utils.fillRect( trasp_bg, -10000, -10000, 20000, 20000, 0, 0.0 );
      //trasp_bg.visible = false;
      //addChild( trasp_bg );

      addEventListener(MouseEvent.MOUSE_DOWN, onLineDown );
      
      // Scroll arrows
      arrow1 = new HUGScrollButton( 0, 0, false );
      addChild( arrow1 );
      arrow1.addEventListener( Event.SCROLL, onUpScroll );

      arrow2 = new HUGScrollButton( 0, h - 16, true);
      addChild( arrow2 );
      arrow2.addEventListener( Event.SCROLL, onDownScroll );
      
      // Slider
      slider = new HUGSprite();
      slider.buttonMode = true;
      slider.x = 0;
      slider.y = SLIDER_POS_Y;
      slider.buttonMode = true;
      slider.useHandCursor = true;

      redrawSlider();
      
      slider.addEventListener( MouseEvent.MOUSE_OVER, onSliderOver );
      slider.addEventListener( MouseEvent.MOUSE_OUT, onSliderOut );
      slider.addEventListener( MouseEvent.MOUSE_DOWN, onSliderDown );
      
      addChild( slider );
      
      //
      setHeight( h );
    }
    
    public function setHeight( h:Int )
    {
      this.h = h;
      recalcSliderLen();
    }

    public function init( maxScrollPos:Int, pageSize:Int )
    {
      maxPos = (maxScrollPos < 0) ? 0 : maxScrollPos;
      pageSz = pageSize;
      
      recalcSliderLen();
    }
/*
    public override function get width():Int
    {
      return 16;
    }

    public override function get height():Int
    {
      return h;
    }
*/
    // scrollPosition
    public function getScrollPosition():Float
    {
      if ( sliderMaxY <= 0 ) {
        return 0;
	  }
	  return Math.round((maxPos * curPos) / sliderMaxY);
    }
    
    public function setScrollPosition( val:Float )
    {
      if ( maxPos == 0 )
      {
        slider.y = SLIDER_POS_Y;
        return;
      }
      
      if ( val < 0 ) val = 0;
      if ( val > maxPos ) val = maxPos;
      
      curPos = (sliderMaxY * val) / maxPos;
      slider.y = SLIDER_POS_Y + curPos;
    }
    
    // ----------------------------------------------------------------------- private methods.
    private function redrawSlider()
    {
      this.graphics.clear();
      slider.graphics.clear();
	 
      
      // ScrollBar background
      Utils.rect( this, 0, 0, W, h, 0xFAFAFA, 0xcccccc );
      
      // Slider
      //Utils.draw3dBar( slider, 1, 1, W - 2, sliderLen - 1, isOver || dragging, true );
      
      var c: UInt = (isOver || dragging) ? Utils.SEL_BG_COL : Utils.ARROW_BG_COL;
      var bc: UInt = (isOver || dragging) ? Utils.SEL_BG_BORDER_COL : Utils.BORDER2_COL;
      Utils.rect( slider, 0, 0, W, sliderLen, c, bc );
    }
    
    private function recalcSliderLen()
    {
      var hh:Int = h - 2*SLIDER_POS_Y + 1;
      
      if ( maxPos + pageSz > 0 )
      {
        sliderLen = Math.round( (pageSz * hh) / (maxPos + pageSz) );
        if ( sliderLen > hh ) sliderLen = hh;
        if ( sliderLen < SLIDER_MIN_LEN ) sliderLen = SLIDER_MIN_LEN;
      }        
      else
        sliderLen = SLIDER_MIN_LEN;
      
      sliderMaxY = hh - sliderLen - 1;
	  redrawSlider();
    }

    private function onLineDown( e:MouseEvent )
    {
      if ( e.target != this )
        return;
        
      if ( e.localY >= slider.y  &&  e.localY <= slider.y + sliderLen )
        return;
      
      slider.y = e.localY - sliderLen / 2;
      if ( slider.y < SLIDER_POS_Y ) slider.y = SLIDER_POS_Y;
      if ( slider.y > SLIDER_POS_Y + sliderMaxY ) slider.y = SLIDER_POS_Y + sliderMaxY;
      
      curPos = slider.y - SLIDER_POS_Y;
      dispatchEvent( new Event( Event.SCROLL ) );
    }

    // ----------------------------------------------------------------- Events handlers
    private function onUpScroll( e:Event )
    {
      setScrollPosition(getScrollPosition() - lineScrollSize);
	  dispatchEvent( new Event( Event.SCROLL ) );
    }
    
    private function onDownScroll( e:Event )
    {
      setScrollPosition(getScrollPosition() + lineScrollSize);
	  dispatchEvent( new Event( Event.SCROLL ) );
    }

    private function onSliderOver( e:MouseEvent )
    {
      setChildIndex( slider, numChildren - 1 );
      isOver = true;
      redrawSlider();
    }
    
    private function onSliderOut( e:MouseEvent )
    {
      isOver = false;
      redrawSlider();
    }
    
    private function onSliderDown( e:MouseEvent )
    {
      dragging = true;
      dragY = e.stageY - slider.y;
      
      addChild( trasp_bg );
      //trasp_bg.visible = true;
      
      redrawSlider();
      
	  //WARNING
      Utils.topParent(this).addEventListener( MouseEvent.MOUSE_UP, onUp );
      //this.addEventListener( MouseEvent.MOUSE_UP, onUp );
      Utils.topParent(this).addEventListener( MouseEvent.MOUSE_MOVE, onMove );
      //this.addEventListener( MouseEvent.MOUSE_MOVE, onMove );
	  trace(e.target.parent.localX + "  =  " + e.target.parent.localY);
	  trace( W + "  =  " + h);
	  if (e.target.parent.localX > W || e.target.parent.localX < 0) {
		Utils.topParent(this).removeEventListener( MouseEvent.MOUSE_UP, onUp );
		Utils.topParent(this).removeEventListener( MouseEvent.MOUSE_MOVE, onMove );
	  }
	  
	  if (e.target.parent.localY > h || e.target.parent.localY < 0) {
		Utils.topParent(this).removeEventListener( MouseEvent.MOUSE_UP, onUp );
		Utils.topParent(this).removeEventListener( MouseEvent.MOUSE_MOVE, onMove );
	  }
	  
    }
    
    private function onUp( e:MouseEvent )
    {
      dragging = false;
      
      removeChild( trasp_bg );
      //trasp_bg.visible = false;
      
      redrawSlider();
      
	  Utils.topParent(this).removeEventListener( MouseEvent.MOUSE_UP, onUp );
      //this.removeEventListener( MouseEvent.MOUSE_UP, onUp );
	  Utils.topParent(this).removeEventListener( MouseEvent.MOUSE_MOVE, onMove );
      //this.removeEventListener( MouseEvent.MOUSE_MOVE, onMove );
/*      
      if ( wrapper != null )
      {
        if ( wrapper.parent as DisplayObject != null )
        {
          wrapper.parent.removeEventListener( MouseEvent.MOUSE_UP, onUp );
          wrapper.parent.removeEventListener( MouseEvent.MOUSE_MOVE, onMove );
        }
        else
        {
          wrapper.removeEventListener( MouseEvent.MOUSE_UP, onUp );
          wrapper.removeEventListener( MouseEvent.MOUSE_MOVE, onMove );
        }
      } else
      {
        removeEventListener( MouseEvent.MOUSE_UP, onUp );
        removeEventListener( MouseEvent.MOUSE_MOVE, onMove );
      }
*/
    }
    
    private function onMove( e:MouseEvent )
    {
      if ( dragging )
      {
        slider.y = e.stageY - dragY;
        slider.y = SLIDER_POS_Y + Math.min( sliderMaxY, Math.max( 0, slider.y - SLIDER_POS_Y ) );
        
        curPos = slider.y - SLIDER_POS_Y;
        dispatchEvent( new MouseEvent( MouseEvent.MOUSE_WHEEL ) );
      }
    }

  }
